package czolgisci.map;

import java.awt.Point;
import java.io.IOException;
import java.util.Iterator;
import java.util.NoSuchElementException;

import czolgisci.display.ISpritesIterator;
import czolgisci.tiles.ATile;
import czolgisci.tiles.Bullet;
import czolgisci.tiles.Explosion;
import utils.Sprite;

/**
 * Klasa która przegląda klasę MapManagerContainer i zwraca po kolei
 * wszystkie elementy w postaci obiektów typu Sprite
 * 
 * @author kasztan
 * @version 1.0
 */
public class MapManagerIterator implements ISpritesIterator
{
	private MapManager mapManagerInstance;
	private int i, j, mapWidth, mapHeight;
	private boolean ended;
	private Iterator<Bullet> bullets;
	private Iterator<Explosion> explosions;

	public MapManagerIterator(MapManager mapManagerIns) throws IllegalArgumentException
	{
		if(mapManagerIns == null)
		{
			throw new IllegalArgumentException();
		}
		mapManagerInstance = mapManagerIns;
		i = -2;
		j = 0;
		ended = false;
		bullets = mapManagerIns.getBulletsIterator();
		explosions = mapManagerIns.getExplosionsIterator();
		mapHeight = mapManagerInstance.getVerticalTilesNum();
		mapWidth = mapManagerInstance.getHorizontalTilesNum();
	}
	/* (non-Javadoc)
	 * @see java.util.Iterator#hasNext()
	 */
	public boolean hasNext()
	{
		return !ended;
	}

	/* (non-Javadoc)
	 * @see java.util.Iterator#next()
	 */
	private boolean BEHasNext()
	{
		return bullets.hasNext() || explosions.hasNext(); 
	}
	
	private ATile BENext()
	{
		if(bullets.hasNext())
			return bullets.next();
		else
			return explosions.next();
	}
	
	public Sprite next() throws NoSuchElementException
	{
		if(ended) throw new NoSuchElementException();
		if(i == -2) // pierwszy element - tło mapy
		{
			i = -1;
			try
			{
				return new Sprite(mapManagerInstance.getBackground(), new Point(0, 0));
			} catch (IOException e)
			{
				e.printStackTrace();
			}
		}
		// pierwszy element tablicy
		if(++i >= mapWidth) 
		{
			i = 0; // element przekroczył zakres, przechodzimy
			j++;   // do nastepnego wiersza
		}
		if(j == mapHeight-1 && i == mapWidth-1)
		{
			if(!BEHasNext())
			{
				ended = true;
			}
		}
		
		if(j >= mapHeight) // jesli koniec
		{
			ATile t = BENext();
			if(!BEHasNext())
			{
				ended = true;
			}
			return new Sprite(t.getImage(), t.getPosition());
		}
		
		ATile tmp = mapManagerInstance.getTileFromIJ(i, j);
		if(tmp == null)
			return next();
		else
			return new Sprite(tmp.getImage(), tmp.getPosition());
	}

	/* (non-Javadoc)
	 * @see java.util.Iterator#remove()
	 */
	public void remove()
	{
		//nie można usunąć elementu
	}
}
